use std::fmt::{Debug, Display};

use crate::{server::Server, utils::async_trait};
use async_std::io;

mod parsed_listener;
mod tcp_listener;
mod to_listener_impls;

pub use parsed_listener::ParsedListener;

///监听器是否需要延时
#[cfg(feature = "h1-server")]
pub(crate) fn is_transient_error(e: &io::Error) -> bool {
    use io::ErrorKind::*;

    matches!(
        e.kind(),
        ConnectionRefused | ConnectionAborted | ConnectionReset
    )
}

pub trait ToListener {
    type Listener: Listener;

    fn to_listener(self) -> io::Result<Self::Listener>;
}

#[async_trait]
pub trait Listener: Debug + Display + Send + Sync + 'static {
    async fn bind(&mut self, app: Server) -> io::Result<()>;

    async fn accept(&mut self) -> io::Result<()>;

    fn info(&self) -> Vec<ListenInfo>;
}

///当前Listener的详细信息
#[derive(Debug, Clone)]
pub struct ListenInfo {
    conn_string: String,
    transport: String,
    tls: bool,
}

impl ListenInfo {
    pub fn new(conn_string: String, transport: String, tls: bool) -> Self {
        Self {
            conn_string,
            transport,
            tls,
        }
    }

    pub fn connection(&self) -> &str {
        self.conn_string.as_str()
    }

    pub fn transport(&self) -> &str {
        self.transport.as_str()
    }

    pub fn is_encrypted(&self) -> bool {
        self.tls
    }
}

impl Display for ListenInfo {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.conn_string)
    }
}
